package forkjoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * Fork/Join框架 work-stealing mechanics
 * 需要 ForkJoinTask & ForkJoinPool
 * RecursiveAction: 无结果任务
 * RecursiveTask: 有结果任务
 * 
 * fork: 放入队列 调用 signalWork 创建线程执行任务
 * join: 调用 doJoin 获取状态 根据状态返回结果
 * 
 * @author insight
 * @since 2021/9/24
 */
public class ForkJoinTest {
    public static void main(String[] args) throws ExecutionException,
            InterruptedException {
        ForkJoinPool pool = new ForkJoinPool();
        SumTask task = new SumTask(1, 1000, 100);
        ForkJoinTask<Integer> ret = pool.submit(task);

        System.out.println(ret.get());

        // 异常处理
        if (task.isCompletedAbnormally()) {
            System.out.println(task.getException().toString());
        }
    }

    private static class SumTask extends RecursiveTask<Integer> {
        private int st, ed;
        private int threshold;

        private SumTask(int st, int ed) {
            this.st = st;
            this.ed = ed;
        }

        public SumTask(int st, int ed, int threshold) {
            this.st = st;
            this.ed = ed;
            this.threshold = threshold;
        }

        @Override
        protected Integer compute() {
            int sum = 0;

            if ((ed - st) <= threshold) {
                sum += (st + ed) / 2 * (ed - st + 1);
            } else {
                int mid = (st + ed) >> 1;
                SumTask left = new SumTask(st, mid);
                SumTask right = new SumTask(mid + 1, ed);
                left.fork();
                right.fork();
                Integer lRet = left.join();
                Integer rRet = right.join();
                sum = lRet + rRet;
            } 
            
            return sum;
        }
    }
    
}